#include "ChatServer.hpp"
#include "ChatService.hpp"
#include <functional>
using namespace std::placeholders;
ChatServer::ChatServer(muduo::net::EventLoop *loop,
                       const muduo::net::InetAddress &iNetAddress,
                       const std::string &name)
    : _loop(loop), _tcpServer(loop, iNetAddress, name)
{
    // 注册链接事件的回调函数
    _tcpServer.setConnectionCallback(std::bind(&ChatServer::OnConnection, this, _1));
    // 注册IO事件的回调函数
    _tcpServer.setMessageCallback(std::bind(&ChatServer::OnMessage, this, _1, _2, _3));

    _tcpServer.setThreadNum(4);
};

// 将start添加到epoll关系事件中
void ChatServer::start()
{
    _tcpServer.start();
}

void ChatServer::OnConnection(const muduo::net::TcpConnectionPtr &conn)
{
    // 客户端断开链接，那么把其对应的端口释放
    // 注意 ： 这里发生异常了，我们直接kill掉客户端了，后续会有跟合理的异常处理策略
    if (!conn->connected())
    {
        // 链接不成功我们就处理这种异常链接的情况（注意可能是客户端正常退出导致的，但是我们这里称之为“异常链接”）
        ChatService::instance()->ClinetConnetionException(conn);
        conn->shutdown();
    }
}

// 就是利用了OnMessage事件的就绪，因为在一开始我们就做了绑定
void ChatServer::OnMessage(const muduo::net::TcpConnectionPtr &conn,
                           muduo::net::Buffer *buffer,
                           muduo::Timestamp time)
{
    std::string buf = buffer->retrieveAllAsString();
    // 将json反序列一下,注意 通过json对象序列化为string对象，反序列化就应该会到json对象这个状态
    json recv = json::parse(buf);
    // 使用recv的收到的 “Message id” 调用相应的回调函数
    auto megHandler = ChatService::instance()->getHandler(recv["msgId"].get<int>());
    megHandler(conn, recv, time);
}
